"""
查询扩展模块

提供查询扩展、同义词替换和语义增强功能。
"""

from typing import List, Dict, Optional, Any, Set, Tuple
import json
import os
from pathlib import Path


class QueryExpander:
    """
    查询扩展器

    提供多种查询扩展策略，包括同义词扩展、近义词替换、相关词添加等。
    """

    def __init__(self, config: Optional[Dict[str, Any]] = None):
        """
        初始化查询扩展器

        Args:
            config: 扩展配置
        """
        self.config = config or {}
        self.synonyms_dict = {}
        self.related_terms_dict = {}
        self.expansion_methods = self.config.get('methods', ['synonyms', 'related'])
        self.max_expansions = self.config.get('max_expansions', 5)
        self.expansion_weight = self.config.get('expansion_weight', 0.3)

        # 加载词典
        self._load_dictionaries()

    def _load_dictionaries(self) -> None:
        """加载同义词和相关词词典"""
        # 默认同义词词典
        self.synonyms_dict = {
            '人工智能': ['AI', '机器学习', '深度学习', '智能技术'],
            '机器学习': ['ML', '机器智能', '统计学习', '算法学习'],
            '深度学习': ['DL', '神经网络', '深度神经网络', 'DNN'],
            '自然语言处理': ['NLP', '语言理解', '文本处理', '语言技术'],
            '计算机视觉': ['CV', '图像识别', '视觉计算', '图像处理'],
            '数据科学': ['DS', '数据分析', '数据挖掘', '大数据'],
            '算法': ['algo', '运算法则', '计算方法', '解题方法'],
            '模型': ['model', '模型结构', '数学模型', '预测模型'],
            '训练': ['training', '学习', '模型训练', '参数优化'],
            '预测': ['prediction', 'forecast', '推断', '预估'],
            '分类': ['classification', '类别识别', '归类', '划分'],
            '聚类': ['clustering', '分组', '群组分析', '无监督学习'],
            '回归': ['regression', '拟合', '数值预测', '连续值预测'],
            '优化': ['optimization', '最优化', '改进', '提升'],
            '特征': ['feature', '属性', '特点', '表征'],
            '准确率': ['accuracy', '精确度', '正确率', '精度'],
            '召回率': ['recall', '查全率', '召回', '检全率'],
            '评估': ['evaluation', '评价', '测评', '性能评估'],
            '框架': ['framework', '架构', '平台', '基础架构'],
            '工具': ['tool', 'utility', '软件工具', '实用工具'],
            '技术': ['technology', 'tech', '技法', '工艺'],
            '方法': ['method', 'approach', '方式', '途径'],
            '系统': ['system', '体系', '架构系统', '整体方案'],
            '应用': ['application', 'app', '使用', '运用'],
            '实现': ['implementation', 'realize', '落实', '达成'],
            '解决方案': ['solution', '解决方法', '处理方案', '答案'],
            '分析': ['analysis', '解析', '剖析', '研究'],
            '处理': ['processing', 'handle', '操作', '执行'],
            '计算': ['computation', 'calculation', '运算', '演算'],
            '数据': ['data', '信息', '资料', '数值'],
            '信息': ['information', 'info', '消息', '情报'],
            '知识': ['knowledge', 'know-how', '认知', '学问'],
            '智能': ['intelligence', 'smart', '智慧', '智能化'],
            '自动化': ['automation', 'auto', '自动', '机械化'],
            '效率': ['efficiency', '效能', '效率性', '绩效'],
            '性能': ['performance', 'perf', '表现', '功能'],
            '质量': ['quality', '品质', '质地', '水准'],
            '管理': ['management', 'admin', '管控', '治理'],
            '监控': ['monitoring', 'monitor', '监督', '观测'],
            '维护': ['maintenance', 'maintain', '保养', '维修'],
            '开发': ['development', 'dev', '研发', '开发工作'],
            '设计': ['design', '规划设计', '构建设计', '方案设计'],
            '测试': ['testing', 'test', '检验', '验证'],
            '部署': ['deployment', 'deploy', '配置', '安装'],
            '集成': ['integration', 'integrate', '整合', '融合'],
            '接口': ['interface', 'API', '界面接口', '连接口'],
            '网络': ['network', 'net', '计算机网络', '网络系统'],
            '安全': ['security', 'safety', '防护', '保障'],
            '隐私': ['privacy', '私密性', '隐私保护', '个人信息'],
            '用户': ['user', '使用者', '客户', '操作者'],
            '体验': ['experience', 'UX', '用户体验', '感受'],
            '交互': ['interaction', 'interactive', '互动', '交流'],
            '界面': ['interface', 'UI', '用户界面', '操作界面'],
            '流程': ['process', 'procedure', '工作流', '操作流程'],
            '标准': ['standard', '规范', '准则', '基准'],
            '协议': ['protocol', '约定', '规约', '通信协议'],
            '格式': ['format', '数据格式', '文件格式', '表达格式'],
            '版本': ['version', 'ver', '版本号', '迭代版本'],
            '更新': ['update', 'upgrade', '升级', '更新版本'],
            '配置': ['configuration', 'config', '设置', '参数配置'],
            '参数': ['parameter', 'param', '变量', '设定值'],
            '变量': ['variable', 'var', '变化量', '可变参数'],
            '常量': ['constant', 'const', '固定值', '不变量'],
            '函数': ['function', 'func', '方法', '功能函数'],
            '程序': ['program', 'code', '编程', '代码'],
            '代码': ['code', 'source code', '源代码', '程序代码'],
            '脚本': ['script', '编程脚本', '执行脚本', '自动化脚本'],
            '文档': ['document', 'doc', '资料文档', '说明文档'],
            '日志': ['log', '日志记录', '运行日志', '系统日志'],
            '错误': ['error', 'exception', '异常', '故障'],
            '警告': ['warning', 'warn', '警报', '提示警告'],
            '状态': ['status', 'state', '运行状态', '当前状态'],
            '结果': ['result', 'outcome', '输出结果', '处理结果'],
            '输入': ['input', '录入', '数据输入', '信息输入'],
            '输出': ['output', '导出', '数据输出', '信息输出']
        }

        # 默认相关词词典
        self.related_terms_dict = {
            '人工智能': ['神经网络', '算法', '模型', '数据', '计算'],
            '机器学习': ['数据', '算法', '模型', '训练', '预测'],
            '深度学习': ['神经网络', 'GPU', '大数据', '模型', '训练'],
            '数据分析': ['统计', '可视化', '报表', '图表', '趋势'],
            '软件开发': ['编程', '代码', '测试', '部署', '维护'],
            '网络安全': ['防火墙', '加密', '认证', '权限', '漏洞'],
            '数据库': ['SQL', '查询', '索引', '存储', '备份'],
            '云计算': ['服务器', '虚拟化', '弹性', '分布式', '容器'],
            '区块链': ['加密货币', '智能合约', '去中心化', '分布式账本', '共识'],
            '物联网': ['传感器', '设备', '连接', '数据', '网络'],
            '大数据': ['数据挖掘', '分析', '存储', '处理', '可视化'],
            '算法': ['复杂度', '优化', '效率', '时间', '空间'],
            '用户': ['客户', '需求', '体验', '反馈', '满意度'],
            '产品': ['功能', '特性', '质量', '价格', '市场'],
            '项目': ['计划', '进度', '团队', '资源', '目标'],
            '技术': ['创新', '研发', '专利', '标准', '趋势']
        }

    def expand_query(
        self,
        query: str,
        keywords: Optional[List[str]] = None,
        methods: Optional[List[str]] = None,
        max_expansions: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        扩展查询

        Args:
            query: 原始查询
            keywords: 关键词列表（可选，如果不提供将自动提取）
            methods: 扩展方法列表
            max_expansions: 最大扩展数量

        Returns:
            Dict[str, Any]: 扩展结果
        """
        methods = methods or self.expansion_methods
        max_expansions = max_expansions or self.max_expansions

        # 如果没有提供关键词，简单提取（这里应该集成关键词提取器）
        if keywords is None:
            keywords = self._simple_extract_keywords(query)

        expansion_terms = []
        expansion_info = {
            'synonyms': [],
            'related_terms': [],
            'method_used': []
        }

        for keyword in keywords:
            # 同义词扩展
            if 'synonyms' in methods:
                synonyms = self._get_synonyms(keyword)
                if synonyms:
                    expansion_info['synonyms'].extend([(keyword, syn) for syn in synonyms])
                    expansion_terms.extend(synonyms[:max_expansions])
                    expansion_info['method_used'].append('synonyms')

            # 相关词扩展
            if 'related' in methods:
                related = self._get_related_terms(keyword)
                if related:
                    expansion_info['related_terms'].extend([(keyword, rel) for rel in related])
                    expansion_terms.extend(related[:max_expansions])
                    expansion_info['method_used'].append('related')

        # 去重
        expansion_terms = list(dict.fromkeys(expansion_terms))

        # 限制扩展词数量
        expansion_terms = expansion_terms[:max_expansions]

        # 构建扩展查询
        expanded_query = query
        if expansion_terms:
            expanded_query = f"{query} {' '.join(expansion_terms)}"

        return {
            'original_query': query,
            'expanded_query': expanded_query,
            'expansion_terms': expansion_terms,
            'expansion_count': len(expansion_terms),
            'expansion_info': expansion_info,
            'expansion_ratio': len(expansion_terms) / len(keywords) if keywords else 0
        }

    def _simple_extract_keywords(self, text: str) -> List[str]:
        """简单的关键词提取"""
        import re
        # 按标点和空格分词
        words = re.split(r'[,\s.!?;:()（）【】\[\]{}""''《》]+', text)
        # 过滤空字符串和短词
        keywords = [word.strip() for word in words if len(word.strip()) > 1]
        return keywords

    def _get_synonyms(self, word: str) -> List[str]:
        """获取同义词"""
        # 直接匹配
        if word in self.synonyms_dict:
            return self.synonyms_dict[word]

        # 模糊匹配（检查是否有词包含这个关键词）
        for key, synonyms in self.synonyms_dict.items():
            if word in key or key in word:
                return [syn for syn in synonyms if syn != word]

        return []

    def _get_related_terms(self, word: str) -> List[str]:
        """获取相关词"""
        # 直接匹配
        if word in self.related_terms_dict:
            return self.related_terms_dict[word]

        # 模糊匹配
        for key, related in self.related_terms_dict.items():
            if word in key or key in word:
                return [rel for rel in related if rel != word]

        return []

    def add_synonym(self, word: str, synonyms: List[str]) -> None:
        """
        添加同义词

        Args:
            word: 原词
            synonyms: 同义词列表
        """
        if word not in self.synonyms_dict:
            self.synonyms_dict[word] = []
        self.synonyms_dict[word].extend(synonyms)
        # 去重
        self.synonyms_dict[word] = list(set(self.synonyms_dict[word]))

    def add_related_terms(self, word: str, terms: List[str]) -> None:
        """
        添加相关词

        Args:
            word: 原词
            terms: 相关词列表
        """
        if word not in self.related_terms_dict:
            self.related_terms_dict[word] = []
        self.related_terms_dict[word].extend(terms)
        # 去重
        self.related_terms_dict[word] = list(set(self.related_terms_dict[word]))

    def calculate_expansion_quality(
        self,
        original_query: str,
        expanded_query: str,
        relevant_docs_count: int = 0,
        total_docs_count: int = 100
    ) -> Dict[str, Any]:
        """
        计算扩展质量

        Args:
            original_query: 原始查询
            expanded_query: 扩展查询
            relevant_docs_count: 相关文档数量
            total_docs_count: 总文档数量

        Returns:
            Dict[str, Any]: 质量评估结果
        """
        # 计算长度增长率
        length_ratio = len(expanded_query) / len(original_query) if original_query else 1

        # 计算词汇增长率
        original_words = set(original_query.split())
        expanded_words = set(expanded_query.split())
        word_ratio = len(expanded_words) / len(original_words) if original_words else 1

        # 计算检索改进率（如果有相关文档数据）
        if relevant_docs_count > 0 and total_docs_count > 0:
            retrieval_rate = relevant_docs_count / total_docs_count
            # 假设基础检索率为10%，扩展后的改进
            base_rate = 0.1
            improvement = (retrieval_rate - base_rate) / base_rate if base_rate > 0 else 0
        else:
            retrieval_rate = 0
            improvement = 0

        # 综合质量得分
        quality_score = 0
        if 1.2 <= length_ratio <= 3.0:  # 合理的长度增长
            quality_score += 0.3
        if 1.1 <= word_ratio <= 2.5:  # 合理的词汇增长
            quality_score += 0.3
        if improvement > 0:
            quality_score += 0.4

        return {
            'quality_score': min(quality_score, 1.0),
            'length_ratio': round(length_ratio, 2),
            'word_ratio': round(word_ratio, 2),
            'retrieval_rate': round(retrieval_rate, 3),
            'improvement_rate': round(improvement, 2),
            'assessment': self._get_quality_assessment(quality_score)
        }

    def _get_quality_assessment(self, score: float) -> str:
        """获取质量评估描述"""
        if score >= 0.8:
            return "优秀"
        elif score >= 0.6:
            return "良好"
        elif score >= 0.4:
            return "一般"
        else:
            return "需要改进"

    def batch_expand(
        self,
        queries: List[str],
        methods: Optional[List[str]] = None
    ) -> List[Dict[str, Any]]:
        """
        批量扩展查询

        Args:
            queries: 查询列表
            methods: 扩展方法列表

        Returns:
            List[Dict[str, Any]]: 扩展结果列表
        """
        results = []

        for i, query in enumerate(queries):
            try:
                expansion_result = self.expand_query(query, methods=methods)
                result = {
                    'index': i,
                    'original_query': query,
                    'success': True,
                    'expansion_result': expansion_result
                }
                results.append(result)
            except Exception as e:
                result = {
                    'index': i,
                    'original_query': query,
                    'success': False,
                    'error': str(e),
                    'expansion_result': None
                }
                results.append(result)

        return results

    def get_dictionary_stats(self) -> Dict[str, Any]:
        """获取词典统计信息"""
        synonym_entries = len(self.synonyms_dict)
        related_entries = len(self.related_terms_dict)
        total_synonyms = sum(len(synonyms) for synonyms in self.synonyms_dict.values())
        total_related = sum(len(related) for related in self.related_terms_dict.values())

        return {
            'synonym_dictionary': {
                'entries': synonym_entries,
                'total_synonyms': total_synonyms,
                'avg_synonyms_per_entry': round(total_synonyms / synonym_entries, 1) if synonym_entries > 0 else 0
            },
            'related_terms_dictionary': {
                'entries': related_entries,
                'total_related_terms': total_related,
                'avg_related_per_entry': round(total_related / related_entries, 1) if related_entries > 0 else 0
            },
            'total_dictionary_size': synonym_entries + related_entries
        }

    def export_dictionaries(self, file_path: str) -> bool:
        """
        导出词典到文件

        Args:
            file_path: 导出文件路径

        Returns:
            bool: 是否成功导出
        """
        try:
            dictionaries = {
                'synonyms': self.synonyms_dict,
                'related_terms': self.related_terms_dict,
                'metadata': {
                    'export_time': str(Path(file_path).stat().st_mtime),
                    'version': '1.0'
                }
            }

            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(dictionaries, f, ensure_ascii=False, indent=2)

            return True
        except Exception as e:
            print(f"导出词典失败: {e}")
            return False

    def import_dictionaries(self, file_path: str) -> bool:
        """
        从文件导入词典

        Args:
            file_path: 导入文件路径

        Returns:
            bool: 是否成功导入
        """
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                dictionaries = json.load(f)

            if 'synonyms' in dictionaries:
                self.synonyms_dict.update(dictionaries['synonyms'])

            if 'related_terms' in dictionaries:
                self.related_terms_dict.update(dictionaries['related_terms'])

            return True
        except Exception as e:
            print(f"导入词典失败: {e}")
            return False

    def __str__(self) -> str:
        """返回扩展器信息的字符串表示"""
        stats = self.get_dictionary_stats()
        return f"""
=== 查询扩展器 ===
支持方法: {', '.join(self.expansion_methods)}
同义词条目: {stats['synonym_dictionary']['entries']}
相关词条目: {stats['related_terms_dictionary']['entries']}
最大扩展数: {self.max_expansions}
扩展权重: {self.expansion_weight}
        """.strip()